import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

enum MachineStatus {
    IDLE("空闲", "可分配任务"),
    WORKING("作业中", "正在执行任务"),
    MAINTENANCE("维修中", "不可用"),
    OFFLINE("离线", "无法连接"),
    LOW_FUEL("低油量", "需要加油");

    private String description;
    private String actionHint;

    MachineStatus(String description, String actionHint) {
        this.description = description;
        this.actionHint = actionHint;
    }

    public String getDescription() {
        return description;
    }

    public String getActionHint() {
        return actionHint;
    }

    public boolean isAvailable() {
        return this == IDLE;
    }
}

// 农机接口
public interface FarmMachine {
    String getMachineId();
    String getMachineType();
    void updateStatus(MachineStatus status);
    MachineStatus getCurrentStatus();
    void assignTask(String task);
    double getFuelLevel();
    void setFuelLevel(double level);
    String getLocation();
    void setLocation(String location);
    String getCurrentTask();
    void displayStatus();
}// 农机基类
abstract class BaseFarmMachine implements FarmMachine {
    protected String machineId;
    protected MachineStatus currentStatus;
    protected double fuelLevel;
    protected String location;
    protected String currentTask;

    public BaseFarmMachine(String machineId) {
        this.machineId = machineId;
        this.currentStatus = MachineStatus.IDLE;
        this.fuelLevel = 100.0; // 初始油量100%
        this.location = "仓库";
        this.currentTask = "无";
    }

    @Override
    public String getMachineId() {
        return machineId;
    }

    @Override
    public void updateStatus(MachineStatus status) {
        this.currentStatus = status;
        System.out.printf("农机 %s 状态更新为: %s (%s)%n",
                machineId, status.getDescription(), status.getActionHint());

        // 低油量自动检测
        if (fuelLevel < 15.0 && status != MachineStatus.LOW_FUEL) {
            this.currentStatus = MachineStatus.LOW_FUEL;
            System.out.printf("警告: 农机 %s 油量过低 (%.1f%%)%n", machineId, fuelLevel);
        }
    }

    @Override
    public MachineStatus getCurrentStatus() {
        return currentStatus;
    }

    @Override
    public void setLocation(String location) {
        this.location = location;
    }

    @Override
    public String getLocation() {
        return location;
    }

    @Override
    public void setFuelLevel(double level) {
        this.fuelLevel = Math.max(0, Math.min(100, level));
        System.out.printf("农机 %s 油量更新为: %.1f%%%n", machineId, fuelLevel);

        // 油量变化可能影响状态
        if (fuelLevel < 15.0) {
            updateStatus(MachineStatus.LOW_FUEL);
        } else if (currentStatus == MachineStatus.LOW_FUEL && fuelLevel >= 15.0) {
            updateStatus(MachineStatus.IDLE);
        }
    }

    @Override
    public double getFuelLevel() {
        return fuelLevel;
    }

    @Override
    public String getCurrentTask() {
        return currentTask;
    }

    @Override
    public void assignTask(String task) {
        if (!currentStatus.isAvailable()) {
            System.out.printf("无法分配任务: 农机 %s 当前状态为 %s%n",
                    machineId, currentStatus.getDescription());
            return;
        }

        this.currentTask = task;
        updateStatus(MachineStatus.WORKING);
        System.out.printf("农机 %s 已分配任务: %s%n", machineId, task);
    }

    @Override
    public void displayStatus() {
        System.out.println("=== 农机状态详情 ===");
        System.out.println("农机ID: " + machineId);
        System.out.println("类型: " + getMachineType());
        System.out.println("状态: " + currentStatus.getDescription());
        System.out.println("状态提示: " + currentStatus.getActionHint());
        System.out.printf("油量: %.1f%%%n", fuelLevel);
        System.out.println("位置: " + location);
        System.out.println("当前任务: " + currentTask);
        System.out.println("=================");
    }
}

// 具体农机类 - 播种机
class SeedingMachine extends BaseFarmMachine {
    public SeedingMachine(String machineId) {
        super(machineId);
    }

    @Override
    public String getMachineType() {
        return "播种机";
    }
}

// 具体农机类 - 喷药机
class SprayingMachine extends BaseFarmMachine {
    public SprayingMachine(String machineId) {
        super(machineId);
    }

    @Override
    public String getMachineType() {
        return "喷药机";
    }
}

// 具体农机类 - 收割机
class HarvestingMachine extends BaseFarmMachine {
    public HarvestingMachine(String machineId) {
        super(machineId);
    }

    @Override
    public String getMachineType() {
        return "收割机";
    }
}// 农机工厂 (工厂方法模式)
interface FarmMachineFactory {
    FarmMachine createMachine(String machineId);
}

class SeedingMachineFactory implements FarmMachineFactory {
    @Override
    public FarmMachine createMachine(String machineId) {
        return new SeedingMachine(machineId);
    }
}

class SprayingMachineFactory implements FarmMachineFactory {
    @Override
    public FarmMachine createMachine(String machineId) {
        return new SprayingMachine(machineId);
    }
}

class HarvestingMachineFactory implements FarmMachineFactory {
    @Override
    public FarmMachine createMachine(String machineId) {
        return new HarvestingMachine(machineId);
    }
}

// 农机代理 (代理模式)
class FarmMachineProxy implements FarmMachine {
    private FarmMachine realMachine;

    public FarmMachineProxy(FarmMachine realMachine) {
        this.realMachine = realMachine;
    }

    @Override
    public String getMachineId() {
        return realMachine.getMachineId();
    }

    @Override
    public String getMachineType() {
        return realMachine.getMachineType();
    }

    @Override
    public void updateStatus(MachineStatus status) {
        System.out.println("[代理] 正在验证状态变更权限...");
        realMachine.updateStatus(status);
    }

    @Override
    public MachineStatus getCurrentStatus() {
        return realMachine.getCurrentStatus();
    }

    @Override
    public void assignTask(String task) {
        System.out.println("[代理] 正在验证任务分配权限...");
        if (!realMachine.getCurrentStatus().isAvailable()) {
            System.out.printf("[代理] 无法分配任务: 农机 %s 当前状态为 %s%n",
                    realMachine.getMachineId(), realMachine.getCurrentStatus().getDescription());
            return;
        }
        realMachine.assignTask(task);
    }

    @Override
    public double getFuelLevel() {
        return realMachine.getFuelLevel();
    }

    @Override
    public void setFuelLevel(double level) {
        System.out.println("[代理] 正在验证油量更新权限...");
        realMachine.setFuelLevel(level);
    }

    @Override
    public String getLocation() {
        return realMachine.getLocation();
    }

    @Override
    public void setLocation(String location) {
        System.out.println("[代理] 正在验证位置更新权限...");
        realMachine.setLocation(location);
    }

    @Override
    public String getCurrentTask() {
        return realMachine.getCurrentTask();
    }

    @Override
    public void displayStatus() {
        System.out.println("[代理] 获取农机状态:");
        realMachine.displayStatus();
    }
}// 农机管理器
class FarmMachineManager {
    private Map<String, FarmMachine> machines = new HashMap<>();

    public void showMenu() {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("\n=== 农机设备管理 ===");
            System.out.println("1. 添加新农机");
            System.out.println("2. 查看所有农机状态");
            System.out.println("3. 查看单个农机详情");
            System.out.println("4. 分配农机任务");
            System.out.println("5. 更新农机状态");
            System.out.println("6. 更新农机油量");
            System.out.println("7. 更新农机位置");
            System.out.println("0. 返回上级菜单");

            int choice = scanner.nextInt();
            scanner.nextLine(); // 消耗换行符

            switch (choice) {
                case 1:
                    addNewMachine(scanner);
                    break;
                case 2:
                    viewAllMachinesStatus();
                    break;
                case 3:
                    viewMachineDetails(scanner);
                    break;
                case 4:
                    assignMachineTask(scanner);
                    break;
                case 5:
                    updateMachineStatus(scanner);
                    break;
                case 6:
                    updateMachineFuel(scanner);
                    break;
                case 7:
                    updateMachineLocation(scanner);
                    break;
                case 0:
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    private void addNewMachine(Scanner scanner) {
        System.out.println("选择农机类型: 1.播种机 2.喷药机 3.收割机");
        int type = scanner.nextInt();
        scanner.nextLine(); // 消耗换行符

        System.out.println("输入农机ID:");
        String machineId = scanner.nextLine();

        if (machines.containsKey(machineId)) {
            System.out.println("错误: 该农机ID已存在！");
            return;
        }

        FarmMachineFactory factory = null;
        switch (type) {
            case 1:
                factory = new SeedingMachineFactory();
                break;
            case 2:
                factory = new SprayingMachineFactory();
                break;
            case 3:
                factory = new HarvestingMachineFactory();
                break;
            default:
                System.out.println("无效的农机类型！");
                return;
        }

        FarmMachine machine = factory.createMachine(machineId);
        FarmMachine proxy = new FarmMachineProxy(machine);
        machines.put(machineId, proxy);
        System.out.println("农机 " + machineId + " 创建成功！");
    }

    private void viewAllMachinesStatus() {
        if (machines.isEmpty()) {
            System.out.println("当前没有注册的农机设备。");
            return;
        }

        System.out.println("\n=== 所有农机状态概览 ===");
        System.out.printf("%-12s%-10s%-12s%-10s%-15s%n",
                "农机ID", "类型", "状态", "油量", "当前任务");

        for (FarmMachine machine : machines.values()) {
            System.out.printf("%-12s%-10s%-12s%-10.1f%%%-15s%n",
                    machine.getMachineId(),
                    machine.getMachineType(),
                    machine.getCurrentStatus().getDescription(),
                    machine.getFuelLevel(),
                    machine.getCurrentTask());
        }
    }

    private void viewMachineDetails(Scanner scanner) {
        System.out.println("输入农机ID:");
        String machineId = scanner.nextLine();

        FarmMachine machine = machines.get(machineId);
        if (machine == null) {
            System.out.println("错误: 未找到该农机设备！");
            return;
        }

        machine.displayStatus();
    }

    private void assignMachineTask(Scanner scanner) {
        System.out.println("输入农机ID:");
        String machineId = scanner.nextLine();

        FarmMachine machine = machines.get(machineId);
        if (machine == null) {
            System.out.println("错误: 未找到该农机设备！");
            return;
        }

        System.out.println("输入任务描述:");
        String task = scanner.nextLine();

        machine.assignTask(task);
    }

    private void updateMachineStatus(Scanner scanner) {
        System.out.println("输入农机ID:");
        String machineId = scanner.nextLine();

        FarmMachine machine = machines.get(machineId);
        if (machine == null) {
            System.out.println("错误: 未找到该农机设备！");
            return;
        }

        System.out.println("当前状态: " + machine.getCurrentStatus().getDescription());
        System.out.println("选择新状态: 1.空闲 2.作业中 3.维修中 4.离线");
        int statusChoice = scanner.nextInt();

        MachineStatus newStatus;
        switch (statusChoice) {
            case 1:
                newStatus = MachineStatus.IDLE;
                break;
            case 2:
                newStatus = MachineStatus.WORKING;
                break;
            case 3:
                newStatus = MachineStatus.MAINTENANCE;
                break;
            case 4:
                newStatus = MachineStatus.OFFLINE;
                break;
            default:
                System.out.println("无效状态选择！");
                return;
        }

        machine.updateStatus(newStatus);
    }

    private void updateMachineFuel(Scanner scanner) {
        System.out.println("输入农机ID:");
        String machineId = scanner.nextLine();

        FarmMachine machine = machines.get(machineId);
        if (machine == null) {
            System.out.println("错误: 未找到该农机设备！");
            return;
        }

        System.out.printf("当前油量: %.1f%%%n", machine.getFuelLevel());
        System.out.println("输入新油量 (0-100):");
        double fuelLevel = scanner.nextDouble();

        machine.setFuelLevel(fuelLevel);
    }

    private void updateMachineLocation(Scanner scanner) {
        System.out.println("输入农机ID:");
        String machineId = scanner.nextLine();

        FarmMachine machine = machines.get(machineId);
        if (machine == null) {
            System.out.println("错误: 未找到该农机设备！");
            return;
        }

        System.out.println("当前位置: " + machine.getLocation());
        System.out.println("输入新位置:");
        String location = scanner.nextLine();

        machine.setLocation(location);
    }
}
